<template>
  <div>
    <h3>toRef响应式工具</h3>
    <p>
      将对象中的某一个比较常用的属性，或者是组件模板中的使用次数较多，为了使用方便，使用toRef对这个属性进行单独获取。
    </p>
    <h3>toRefs响应式工具</h3>
    <p>将整个响应对象的所有属性，使用toRef对每个属性进行单独获取。</p>
    <h3>m: {{ users.other.data.m }}</h3>
    <p>a: {{ a }}, b: {{ b }}</p>
    <button @click="sendData">发射事件</button>
    <div>
      <p>uname: {{ users.uname }}</p>
      <p>uage: {{ users.uage }}</p>
      <p>m: {{ users.other.data.m }}</p>
    </div>
    <h3>m: {{ users.other.data.m }}</h3>
    <h3>m: {{ m }}</h3>
    <h3>m: {{ m }}</h3>
    <h3>m: {{ m }}</h3>
    <h3>m: {{ m }}</h3>
    <button @click="setM">修改m1</button>
    <button @click="setMM">修改m2</button>
    <div>
      <p>p1: {{ p1 }}</p>
      <p>p2: {{ other.p2 }}</p>
      <button @click="setPeople">修改people</button>
    </div>
  </div>
</template>

<script>
import { reactive, toRef, ref, toRefs } from "@vue/reactivity";
export default {
  name: "Vue3Course01ToRefToRefs",
  props: {
    a: Number,
    b: Number,
  },
  setup(props, context) {
    // 两个参数：
    // props: 接收父组件的传值
    // context: 上下文对象，有三个属性：attrs slots emit
    // attrs: 等价于 this.$attrs 接收子组件未声明的prop
    // emit: 等价于 this.$emit 发射自定义事件，向父组件传值

    // console.log(this);  // this指向undefined
    console.log("props ", props); // props也是一个Proxy对象
    console.log("attrs ", context.attrs);
    console.log("slots ", context.slots);
    const sendData = () => {
      context.emit("setdata", { a: 111 });
    };

    // toRef()
    const users = reactive({
      uname: "小王",
      uage: 22,
      uaddress: "郑州市",
      other: {
        data: {
          m: 1000,
        },
      },
    });
    const setM = () => {
      users.other.data.m = 2000;
    };

    // const m = users.other.data.m; // 这种写法是会丢失响应性的，不建议这样写，除非真的不需要响应式数据了。

    /*
    const m = toRef(users.other.data, "m"); // 将 users.other.data 里面的m属性，单独结构出来，并保证数据的响应性，所以使用toRef结构。它得到的RefImpl对象，具备响应性
    console.log("m = ", m);
    const setMM = () => {
      m.value = 3000;
    };
    */

    const m = ref(users.other.data.m); // users.other.data.m 将这个数据，全新声明了一个ref对象，和源数据已经脱离关系了。
    const setMM = () => {
      m.value = 3000;
    };

    const people = reactive({
      p1: 1,
      other: {
        p2: 2,
      },
    });
    const setPeople = () => {
      people.p1 = 100;
    };
    // console.log(people);
    // const result = toRefs(people);
    // console.log(result);
    return {
      sendData,
      users,
      m,
      setM,
      setMM,
      people,
      setPeople,
      ...toRefs(people),
      // p1, // ObjectRefImpl
      // other, // ObjectRefImpl
    };
  },
};
</script>

<style lang="less" scoped></style>
